<?php

namespace app\admin\controller;

use Throwable;
use ba\Random;
use think\facade\Db;
use app\common\controller\Backend;
use app\common\model\RedemptionCode as ModelRedemptionCode;

/**
 * 兑换码管理
 */
class RedemptionCode extends Backend
{
    /**
     * RedemptionCode模型对象
     * @var object
     * @phpstan-var \app\admin\common\RedemptionCode
     */
    protected object $model;

    protected array|string $preExcludeFields = ['id',  'discount_amount', 'discount_percent', 'admin_id', 'batch_id', 'create_time', 'update_time'];

    protected string|array $quickSearchField = ['code', 'title'];

    public function initialize(): void
    {
        parent::initialize();
        $this->model = new \app\common\model\RedemptionCode();
    }

    /**
     * 查看
     * @throws Throwable
     */
    public function index(): void
    {
        // 如果是 select 则转发到 select 方法，若未重写该方法，其实还是继续执行 index
        if ($this->request->param('select')) {
            $this->select();
        }

        list($where, $alias, $limit, $order) = $this->queryBuilder();
        
        // 添加时间区间查询支持
        $startTime = $this->request->param('start_time', '');
        $endTime = $this->request->param('end_time', '');
        
        if ($startTime) {
            $startTimeStamp = is_numeric($startTime) ? $startTime : strtotime($startTime);
            $where[] = ['start_time', '>=', $startTimeStamp];
        }
        
        if ($endTime) {
            $endTimeStamp = is_numeric($endTime) ? $endTime : strtotime($endTime);
            $where[] = ['end_time', '<=', $endTimeStamp];
        }

        $res = $this->model
            ->withJoin($this->withJoinTable, $this->withJoinType)
            ->alias($alias)
            ->where($where)
            ->order($order)
            ->paginate($limit);

        $this->success('', [
            'list'   => $res->items(),
            'total'  => $res->total(),
            'remark' => get_route_remark(),
        ]);
    }

    /**
     * 添加
     * @throws Throwable
     */
    public function add(): void
    {
        if ($this->request->isPost()) {
            $data = $this->request->post();
            if (!$data) {
                $this->error(__('Parameter %s can not be empty', ['']));
            }

            $data = $this->excludeFields($data);
            if ($this->dataLimit && $this->dataLimitFieldAutoFill) {
                $data[$this->dataLimitField] = $this->auth->id;
            }

            // 转换时间格式为时间戳
            if (isset($data['start_time']) && $data['start_time']) {
                $data['start_time'] = strtotime($data['start_time']);
            }
            if (isset($data['end_time']) && $data['end_time']) {
                $data['end_time'] = strtotime($data['end_time']);
            }

            $result = false;
            Db::startTrans();
            try {
                // 单个兑换码生成
                $data['code'] = ModelRedemptionCode::generateUniqueCode();
                $data['used_count'] = 0;
                $data['status'] = ModelRedemptionCode::STATUS_ACTIVE;
                $data['create_time'] = time();
                $data['update_time'] = time();
                $result = $this->model->save($data);
                
                Db::commit();
            } catch (Throwable $e) {
                Db::rollback();
                $this->error($e->getMessage());
            }
            if ($result !== false) {
                $this->success(__('Added successfully'));
            } else {
                $this->error(__('No rows were added'));
            }
        }

        $this->success('', [
            'remark' => get_route_remark(),
        ]);
    }

    /**
     * 编辑
     * @throws Throwable
     */
    public function edit(): void
    {
        $pk  = $this->model->getPk();
        $id  = $this->request->param($pk);
        $row = $this->model->find($id);
        if (!$row) {
            $this->error(__('Record not found'));
        }

        if ($this->request->isPost()) {
            $data = $this->request->post();
            if (!$data) {
                $this->error(__('Parameter %s can not be empty', ['']));
            }

            $data   = $this->excludeFields($data);
            
            // 转换时间格式为时间戳
            if (isset($data['start_time']) && $data['start_time']) {
                $data['start_time'] = strtotime($data['start_time']);
            }
            if (isset($data['end_time']) && $data['end_time']) {
                $data['end_time'] = strtotime($data['end_time']);
            }
            
            $result = false;
            Db::startTrans();
            try {
                // 不允许修改已使用的兑换码的核心信息
                if ($row->used_count > 0) {
                    unset($data['code'], $data['type'], $data['value'], $data['max_uses']);
                }
                
                $data['update_time'] = time();
                $result = $row->save($data);
                Db::commit();
            } catch (Throwable $e) {
                Db::rollback();
                $this->error($e->getMessage());
            }
            if ($result !== false) {
                $this->success(__('Update successful'));
            } else {
                $this->error(__('No rows updated'));
            }
        }

        // 转换时间戳为时间格式供前端显示
        if ($row->start_time) {
            $row->start_time = date('Y-m-d H:i:s', $row->start_time);
        }
        if ($row->end_time) {
            $row->end_time = date('Y-m-d H:i:s', $row->end_time);
        }

        $this->success('', [
            'row'    => $row,
            'remark' => get_route_remark(),
        ]);
    }

    /**
     * 删除
     * @param array $ids
     * @throws Throwable
     */
    public function del(array $ids = []): void
    {
        if (!$this->request->isDelete() || !$ids) {
            $this->error(__('Parameter error'));
        }

        $dataLimitAdminIds = $this->getDataLimitAdminIds();
        if ($dataLimitAdminIds) {
            $this->model = $this->model->where($this->dataLimitField, 'in', $dataLimitAdminIds);
        }

        $pk    = $this->model->getPk();
        $data  = $this->model->where($pk, 'in', $ids)->select();
        $count = 0;
        Db::startTrans();
        try {
            foreach ($data as $v) {
                // 不允许删除已使用的兑换码
                if ($v->used_count > 0) {
                    continue;
                }
                $count += $v->delete();
            }
            Db::commit();
        } catch (Throwable $e) {
            Db::rollback();
            $this->error($e->getMessage());
        }
        if ($count) {
            $this->success(__('Deleted successfully'));
        } else {
            $this->error(__('No rows were deleted'));
        }
    }

    
    /**
     * 批量操作
     */
    public function batch(): void
    {
        if (!$this->request->isPost()) {
            $this->error(__('Parameter error'));
        }

        $action = $this->request->post('action');
        $ids = $this->request->post('ids');

        if (!$action || !$ids) {
            $this->error(__('Parameter error'));
        }

        $count = 0;
        Db::startTrans();
        try {
            switch ($action) {
                case 'enable':
                    $count = $this->model->where('id', 'in', $ids)->update(['status' => 'active', 'update_time' => time()]);
                    break;
                case 'disable':
                    $count = $this->model->where('id', 'in', $ids)->update(['status' => 'disabled', 'update_time' => time()]);
                    break;
                case 'delete':
                    // 只删除未使用的兑换码
                    $count = $this->model->where('id', 'in', $ids)->where('used_count', 0)->delete();
                    break;
            }
            Db::commit();
        } catch (Throwable $e) {
            Db::rollback();
            $this->error($e->getMessage());
        }

        if ($count) {
            $this->success(__('Operation completed'));
        } else {
            $this->error(__('No rows were affected'));
        }
    }

    /**
     * 导出兑换码
     */
    public function export(): void
    {
        $ids = $this->request->param('ids');
        if (!$ids) {
            $this->error(__('Parameter error'));
        }

        $codes = $this->model->where('id', 'in', $ids)->select();
        if (!$codes) {
            $this->error(__('No data found'));
        }

        $filename = '兑换码导出_' . date('YmdHis') . '.csv';
        header('Content-Type: application/csv');
        header('Content-Disposition: attachment; filename="' . $filename . '"');
        
        $output = fopen('php://output', 'w');
        fputcsv($output, ['兑换码', '批次名称', '类型', '价值', '最大使用次数', '已使用次数', '状态', '过期时间', '描述']);
        
        foreach ($codes as $code) {
            fputcsv($output, [
                $code->code,
                $code->batch_name,
                $code->type,
                $code->value,
                $code->max_uses,
                $code->used_count,
                $code->status,
                $code->expires_at ? date('Y-m-d H:i:s', $code->expires_at) : '永不过期',
                $code->description
            ]);
        }
        
        fclose($output);
        exit;
    }
}